#ifndef _TCPSOCKET_H_
#define _TCPSOCKET_H_

#include "netfwd.h"

#pragma once

class Time_Value;

class NetSocket
{
public:
    NetSocket( int32_t fd = -1, int32_t is_udp = 0 )
        : m_fd( fd ),
          m_is_udp( is_udp )
    {}

    ~NetSocket() throw();

    inline void attach( int32_t fd, int32_t is_udp  = 0 ) {
        m_fd = fd;
        m_is_udp = is_udp;
    }

    inline void detach() { m_fd = -1; }

    inline int32_t getfd() const { return m_fd; };

    inline int32_t is_good() const { return m_fd >= 0 ? 1 : 0; }

    inline int32_t is_udp() const { return m_is_udp; }

    int32_t listen( const char * svrip, int32_t port );

    int32_t accept();

    int32_t connect_nonblock( const struct sockaddr_in * remote_addr );

    int32_t connect_timeout( const struct sockaddr_in * remote_addr, int32_t timeout_sec = 5 );

    int32_t create_udp( const char * localip = NULL, int32_t port = 0 );

    int32_t synch_send( const char * buf, int32_t buf_len );

    int32_t synch_recv( char * buf, int32_t buf_len, const Time_Value & timeout );

    int32_t get_peername( char * buf, int32_t buf_len ) const;

    int32_t get_sockname( char * buf, int32_t buf_len ) const;

    int32_t get_peerip( char * buf, int32_t buf_len ) const;

    int32_t get_peerip() const;

    int32_t send( const char * buf, int32_t buf_len );

    int32_t sendto( const char * buf, int32_t buf_len, const struct sockaddr * dest );

    int32_t recv( char * buf, int32_t buf_len );

    int32_t recvfrom( char * buf, int32_t buf_len, struct sockaddr * dest );

    void close();

    int32_t getsockerror() const;

	static int32_t gethostips( char ** & iplist );

    static int32_t gethostipsbydevname( const char * dev_name, char ** &iplist );

    static int32_t gethostmacaddrs( char ** & macaddr_list );

    static const char * ip_name( int32_t ip_num );

    int32_t maximize_socket_buffer( int32_t optname );

    inline void setupsocket() {
        return setupsocket_i( m_fd );
    }

private:
    void setupsocket_i( int32_t fd );

private:
    enum{ E_SOCKBUF_MAXSIZE = 256 * 1024 * 1024, };
    int32_t     m_fd;
    int32_t     m_is_udp;
};

#endif // _TCPSOCKET_H_

